package influxdb

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/influxdata/influxdb/client/v2"
	"log"
	"sync"
	"time"
)

const (
	Passengerflow              = "passengerflow"
	PassengerflowBusiensss     = "passengerflow_business"
	Passengerflow_physicalzone = "passengerflow_physicalzone"
	Pack5passengerflow         = "pack5passengerflow"
	Pack60Passengerflow        = "pack60passengerflow"
)

var (
	flowFieldSyncOnce sync.Once
	flowFieldMap      map[string]string
)

type Flow struct {
	Time       time.Time
	ZoneId     string
	CountEnter int
	CountExit  int
}

func (c *Connect) SelectFlowByDate(table string, zoneIds []int, date string) *[]Flow {
	return c.SelectFlow(table, zoneIds,
		fmt.Sprintf("%v 00:00:00", date), fmt.Sprintf("%v 23:59:59", date))
}

func (c *Connect) SelectFlow(table string, zoneIds []int, startTime string, endTime string) *[]Flow {
	var buffer bytes.Buffer
	for _, zoneId := range zoneIds {
		sql := fmt.Sprintf("SELECT * FROM %s where zoneid = '%d' and time>='%s' and time<='%s' order by time tz('%s');",
			table, zoneId, startTime, endTime, c.TimeZone)
		buffer.WriteString(sql)
	}
	//log.Println(buffer.String())
	//sysinit.LogDebug(buffer.String())
	res, err := c.queryDB(buffer.String())
	if err != nil {
		log.Println(err)
	}
	return toIpassengerflow(res)
}

func (c *Connect) CopyInsertInto(sourceTable string, targetTable string, startTime string, endTime string, groupBy string) {
	sqlformat := `SELECT time,SUM(countenter) AS countenter,SUM(countexit) AS countexit INTO %s FROM %s where time >= '%s' AND time <='%s' group by zoneid,time(%s) fill(0) order by time  tz('%s') ;`
	sql := fmt.Sprintf(sqlformat, targetTable, sourceTable, startTime, endTime, groupBy, c.TimeZone)
	res, err := c.queryDB(sql)
	if err != nil {
		log.Println(err)
	}
	log.Println(fmt.Sprintf("%v", res))
}

/**
如果插入成功 返回插入的数量，
如果插入失败 返回 -1
*/
func (c *Connect) InsertPassengerflow(flow *[]Flow, tableName string) int {
	var cPoint []*client.Point
	for _, value := range *flow {
		tags := map[string]string{
			"zoneid": value.ZoneId,
		}
		fields := map[string]interface{}{
			"countenter": value.CountEnter,
			"countexit":  value.CountExit,
		}
		pt, err := client.NewPoint(tableName, tags, fields, value.Time)
		if err != nil {
			log.Println(err)
			return -1
		} else {
			cPoint = append(cPoint, pt)
		}
	}
	return c.insert(20000, cPoint)
	//baseNumber := 20000
	//cpointLen := len(cPoint)
	//if cpointLen > baseNumber {
	//	gCount := cpointLen / baseNumber
	//	insertLen := 0
	//	for i := 0; i < gCount; i++ {
	//		insertLen += c.insert(cPoint[baseNumber*i : baseNumber*(i+1)])
	//	}
	//	insertLen += c.insert(cPoint[baseNumber*gCount : cpointLen])
	//	return insertLen
	//} else {
	//	return c.insert(cPoint)
	//}
}

func toIpassengerflow(result []client.Result) *[]Flow {
	resFlow := new([]Flow)
	var rarray []map[string]interface{}
	for _, res := range result {
		if res.Err == "" {
			for _, row := range res.Series {
				cloumns := row.Columns
				for _, values := range row.Values {
					rmap := make(map[string]interface{}, len(cloumns))
					for index, va := range values {
						rmap[cloumns[index]] = va
					}
					rarray = append(rarray, rmap)
				}
			}
		} else {
			log.Println(res.Err)
		}
	}
	rjson, err := json.Marshal(rarray)
	if err != nil {
		log.Println(err)
	}
	json.Unmarshal(rjson, &resFlow)
	return resFlow
}
